﻿using CommunityToolkit.Mvvm.Input;
using HandyControl.Expression.Shapes;
using ImageHandler.Models;
using Microsoft.Win32;
using OpenCvSharp;
using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Windows.Media.Imaging;

namespace ImageHandler.ViewModels
{
    public class E004_ObjectOutlineViewModel : PartViewModel
    {
        public E004_ObjectOutlineViewModel()
        {
            Header = "图像轮廓提取";
        }

        public override void Run(string path)
        {
            // 读取图像，图像灰度
            Mat src = Cv2.ImRead(path, ImreadModes.Color);
            if (src.Empty())
            {
                OperateLogAction?.Invoke("无法读取图像！");
                return;
            }
            Result.ReslutInfos.Clear();

            // 高斯模糊
            Mat gaussianBlurMat = new Mat();
            Cv2.GaussianBlur(src, gaussianBlurMat, new Size(15, 15), 0, 0, BorderTypes.Default);
            AddMatToResultInfos(gaussianBlurMat, "原图->高斯模糊");

            // 转换为灰度图像
            Mat grayMat = new Mat();
            Cv2.CvtColor(gaussianBlurMat, grayMat, ColorConversionCodes.BGR2GRAY);
            AddMatToResultInfos(grayMat, "高斯模糊->灰度图像");

            // 二值化
            Mat binaryMat = new Mat();
            Cv2.Threshold(grayMat, binaryMat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
            AddMatToResultInfos(binaryMat, "灰度图像->二值化");

            // 形态学操作
            Mat morphMat = new Mat();
            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3), new Point(-1, -1));
            Cv2.MorphologyEx(binaryMat, morphMat, MorphTypes.Close, kernel, new Point(-1, -1), 2);
            AddMatToResultInfos(morphMat, "二值化->形态学闭操作");

            // 轮廓检测
            Point[][] contours;
            HierarchyIndex[] hierarchy;
            Cv2.FindContours(morphMat, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
            Mat retMat = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            string result = "";
            for (int i = 0; i < contours.Length; i++)
            {
                Rect rect = Cv2.BoundingRect(contours[i]);
                if (rect.Width < src.Cols / 20)
                    continue;
                if (rect.Width > (src.Cols - 20))
                    continue;
                double area = Cv2.ContourArea(contours[i]);
                double len = Cv2.ArcLength(contours[i], true);
                result += $"轮廓{i + 1}：面积={area}, 周长={len}\t";
                Cv2.DrawContours(retMat, contours, i, new Scalar(0, 255, 0), 2);
            }
            AddMatToResultInfos(retMat, "识别结果");
            Result.Result = result;
        }
    }
}
